import React, { Component } from 'react';
import { Affix, Button, Spin, Icon, Menu, Collapse, message, Modal } from 'antd';
import 'styles/data-center/report-management/custom-report/index.scss';
import { deepCopy, messages, removeArrayItemByKey, scrollToMyDestination } from 'share/common';
import withDragDropContext from 'components/with-dnd-context';
import DragItem from './drag-source/drag-item';
import FakeDropLayout from './drop-target/fake-drop-layout';
import GraphicDropTarget from './drop-target/graphic-drop-target';
import FullScreen from 'components/full-screen';
import EditCustomReport
  from 'containers/data-center/report-management/custom-report/edit-custom-report';
import CustomReportService
  from 'containers/data-center/report-management/custom-report/custom-report.service';
import debounce from 'lodash.debounce';

import {
  graphList,
  tableTemplateList,
  criteriaTemplateList
} from 'containers/data-center/report-management/custom-report/custom-report.modal';
import menuRoute from 'routes/menuRoute';
import AdvancedSearch from 'components/advanced-search';
import UniversalReportService
  from 'containers/data-center/report-management/custom-report/graphic/default-value/custom-report.service';
import { connect } from 'react-redux';
import { clearPending } from 'share/httpFetch';


const Panel = Collapse.Panel;
const confirm = Modal.confirm;

function mapStateToProps(state) {
  return {
    language: state.main.language,
    company: state.login.company,
    tenant: state.login.tenant
  };
}

@connect(mapStateToProps)

class CustomReport extends Component {
  constructor(props) {
    super(props);
    this.state = {
      customReportName: messages('basic-10.key173')/*自定义报表*/, //自定义报表名
      loading: true,
      editVisible: false, //第二层 编辑报表详情 fullScreen 开关
      sourceReportIdArray: [], //所有数据模型ID数组
      widgetList: [], // 图表list
      searchForm: [], // 处理后的 筛选器数据 对应AdvanceSearch 的 searchForm
      criteriaData: [], //筛选器数据 存储的地方
      currentReportPrivate: {}, // 各报表私有配置的载体 (不知道这是干嘛的， 因为格式化 searchForm 需要这个)
      currentEdit: undefined, //进入单个图表编辑时 编辑的对象储存
    };
    this.SingleKey = 1000000; //添加图表时 临时 唯一 key
    this.resizeWindow = debounce(this.resizeWindow, 500); //延时 resize Window
    this.actualDelete = debounce(this.actualDelete, 300); //延时 真正的删除图标
    this.handleOnDragDroppedItem = debounce(this.handleOnDragDroppedItem, 50);
  }

  componentDidMount() {
    this.initData(); //初始化数据
    const { onRef } = this.props;
    onRef && (onRef(this));
  }

  componentWillUnmount() {
    clearPending();
  }

  /** 初始化数据 完成了以下事情：
      1. customReportName  自定义报表名
      2. widgetList 图表 List 包含图表各种信息
      3. criteriaData 筛选器信息 这个在后端数据里 是和 图表 一起的。 所以 筛选器也是 变相的 '图表'
      4. sourceReportIdArray 所有图表的 数据模型 ID 数组 在 编辑筛选器时会用到
      5. searchForm 通过处理 criteriaData 筛选器里的 信息 处理好的 advanceSearch 能识别的 searchForm

      本页面功能：
      1. 图表的增删
      2. 图表的布局修改 全屏/半屏
      3. 图表/筛选器 的 编辑入口
      4. 自定义报表已配置筛选器的展示
      5. 配置好的图表 基于真实数据的展示
  */
  initData = () => {
    this.setState({ loading: true });
    const { customReportData } = this.props;
    CustomReportService.getCustomReportDetail(customReportData.id)
      .then((res) => {
        if (res.status === 200) {
          let copyData = deepCopy(res.data);
          let reportCharts = copyData.reportCharts;
          let sourceReportIdArray = [];
          if (reportCharts && reportCharts.length) {
            res.data.reportCharts.forEach((item, index) => {
              reportCharts[index].uniqueKey = item.id;
              reportCharts[index].key = item.chartType;
              reportCharts[index].set = true;
              if (item.chartType !== 'criteria') {
                sourceReportIdArray.push(item.sourceReportId);
              }
            });
          }
          let widgetList = reportCharts && reportCharts.length && reportCharts.filter(item => item.key !== 'criteria') || [];
          let criteriaData = reportCharts && reportCharts.length && reportCharts.filter(item => item.key === 'criteria') || [];
          let searchForm = this.handleSearchForm(criteriaData[0]);
          sourceReportIdArray = sourceReportIdArray.filter((item, index, self) => self.indexOf(item) === index);
          this.setState({
            customReportName: res.data.reportName,
            widgetList,
            criteriaData,
            sourceReportIdArray,
            searchForm,
            loading: false
          });
        }
      });
  };

  //根据拿到的筛选器数据 格式化 searchForm 数据
  handleSearchForm = (data) => {
    let result = [];
    if (data && data.reportChartDetails && data.reportChartDetails.length) {
      result = UniversalReportService.searchFormFactory({
        context: this,
        list: data.reportChartDetails.map((item) => {
          return {
            criteriaCode: item.criteriaCode,
            criteriaName: item.fieldDisplayName,
            criteriaPropName: `${item.sourceReportId}_${item.criteriaPropName}`,
            defaultValue: item.defaultValue
          };
        })
      });
    }
    return result;
  };

  //点击 页面左上角 返回的处理
  onPageCanceled = () => {
    const { widgetList } = this.state;
    let doseNotFinish = false;
    widgetList.forEach((item) => {
      if (!item.set) {
        doseNotFinish = true;
      }
    });
    if (doseNotFinish) {
      confirm({
        title: messages('basic-10.key99')/*警告*/,
        content: messages('basic-10.key174')/*未完成图表配置，退出会丢失已配置数据，确定退出？*/,
        okText: messages('common.ok')/*确定*/,
        cancelText: messages('common.cancel')/*取消*/,
        onOk: () => {
          this.props.onCancel && this.props.onCancel();
        },
        onCancel() {
        },
      });
    } else {
      this.props.onCancel && this.props.onCancel();
    }
  };
  // 渲染头信息
  renderPageHeader = () => {
    const { customReportName } = this.state;
    return <div className={'page-header'}>
      <div className="left">
        <Icon onClick={this.onPageCanceled} type="left"/>
        <span
          className={'report-name'}>{customReportName || messages('basic-10.key173')/*自定义报表*/}</span>
      </div>
      <div className="right">
        <Button onClick={this.goToPreview}>{messages('basic-10.key57')/*预览*/}</Button>
      </div>
    </div>;
  };

  //前往预览页面
  goToPreview = (e) => {
    e.preventDefault();
    const { customReportData } = this.props;
    let targetRoute = 'custom-report-preview';
    let path = menuRoute.getRouteItem(targetRoute, 'key')
      .url
      .replace(':id', customReportData.id);
    if (path.includes(':reportName')) {
      path = path.replace(':reportName', customReportData.reportName);
    }
    window.open(path, '_blank');
  };

  //拖动新增图形表 松开鼠标时的 插入处理
  handleDrop = (widget, index) => {
    let copySpliceIndex = index;
    let copyWidget = deepCopy(widget);
    const { widgetList, criteriaData } = this.state;
    let data = this.judgeIsOneMore(widgetList);
    if (data.result) {
      message.warn(messages('basic-10.key175',{arg1: data.name})/*请编辑【{arg1}】后，再添加新图表*/);
    } else {
      let copyData = deepCopy(widgetList);
      let currentSequence = copyData.map(item => item.id);
      if (criteriaData.length) {
        currentSequence.unshift(criteriaData[0].id);
        copySpliceIndex += 1;
      }
      copyWidget.order = index;
      copyWidget.uniqueKey = this.SingleKey++;
      copyWidget.currentSequence = currentSequence;
      copyWidget.spliceIndex = copySpliceIndex;
      copyData.splice(index, 0, copyWidget);
      this.setState({ widgetList: copyData, loading: false }, () => {
        // this.delayEditDrag(widget);
      });
    }
  };

  //判断是否有未设置的图形表 返回状态以及该图表名称
  judgeIsOneMore = (widgetList) => {
    let result = false;
    let name = '';
    widgetList.map(item => {
      if (!item.set) {
        result = true;
        name = item.chartName;
      }
    });
    return { result, name };
  };

  //图形表除了拖拽外还可以 点击 直接新增 默认加到 最后     以下为 点击新增处理
  handleItemClick = (item) => {
    let copyItem = deepCopy(item);
    const { widgetList } = this.state;
    let data = this.judgeIsOneMore(widgetList);
    if (data.result) {
      message.warn(messages('basic-10.key175',{arg1: data.name})/*请编辑【{arg1}】后，再添加新图表*/);
    } else {
      let copyData = deepCopy(widgetList);
      copyItem.order = widgetList.length;
      copyItem.uniqueKey = this.SingleKey++;
      copyData.push(copyItem);
      this.setState({ widgetList: copyData }, () => {
        scrollToMyDestination(this.rightRef, this.pageContentRef.clientHeight);
        // this.delayEdit(copyItem);
      });
    }
  };

  // 渲染 可添加的图形表 以及 table 明细表
  renderPageContentLeft = () => {
    return (
      <div className={'page-body-left'}>
        <FakeDropLayout/>
        <Collapse bordered={false} defaultActiveKey={['1', '2']}>
          <Panel header={messages('basic-10.key176')/*图形表*/} key={'1'}>
            {
              graphList.map(widget => <DragItem onItemClick={this.handleItemClick} widget={widget}
                                                key={widget.key}/>)
            }
          </Panel>
          <Panel header={messages('basic-10.key177')/*明细表*/} key={'2'}>
            {
              tableTemplateList.map(widget => <DragItem onItemClick={this.handleItemClick}
                                                        widget={widget} key={widget.key}/>)
            }
          </Panel>
        </Collapse>
      </div>
    );
  };

  //点击 全屏/半屏 图表的处理
  onStretchItem = (widget) => {
    const { widgetList } = this.state;
    let copyData = deepCopy(widgetList);
    widgetList.forEach((chart, index) => {
      if (chart.id === widget.id) {
        copyData[index].changingScreen = true;
      }
    });
    this.setState({ widgetList: copyData }, () => {
      let params = {
        id: widget.id,
        showScreen: widget.showScreen === 'half' ? 'all' : 'half'
      };
      CustomReportService.switchSingleChartScreenSize(params)
        .then((res) => {
          if (res.status === 200) {
            widgetList.forEach((item, index) => {
              if ((item.id === widget.id) || (item.uniqueKey === widget.uniqueKey)) {
                copyData[index].showScreen = (widget.showScreen === 'half' ? 'all' : 'half');
                delete copyData[index].changingScreen;
              }
            });
            this.setState({ widgetList: copyData }, () => {
              this.resizeWindow();
            });
          }
        });
    });
  };

  //手动触发 window resize 好让 echart 图表 重新 渲染 以适配最新的 宽度
  resizeWindow = () => {
    let myEvent = new Event('resize');
    window.dispatchEvent(myEvent);
  };

  //删除图表的处理
  onDeleteItem = (widget) => {
    confirm({
      title: messages('basic-10.key2')/*确认删除*/,
      okText: messages('basic-10.key3')/*确认*/,
      cancelText: messages('common.cancel')/*取消*/,
      iconType: 'exclamation-circle',
      onOk: () => {
        this.setState({ loading: true });
        if (widget.id) {
          let params = { id: widget.id };
          CustomReportService.deleteSingleChart(params)
            .then((res) => {
              if (res.status === 200) {
                this.initData();
              }
            });
        } else {
          this.actualDelete(widget);
        }
      },
      onCancel() {
      },
    });
  };

  //真正的删除 上个function 是处理逻辑的
  actualDelete = (widget) => {
    const { widgetList } = this.state;
    let copyData = deepCopy(widgetList);
    copyData = removeArrayItemByKey(copyData, widget, 'uniqueKey');
    this.setState({ widgetList: copyData, loading: false });
    message.success(messages('common.delete.successful')/*删除成功*/);
  };

  //编辑筛选器/图表
  onEditItem = (widget, editCriteria) => {
    if (editCriteria) {
      const { widgetList } = this.state;
      let length = widgetList && widgetList.length > 0;
      if (length) {
        let doseNotFinish = false;
        let name = '';
        widgetList.forEach((item) => {
          if (!item.set) {
            doseNotFinish = true;
            name = item.chartName;
          }
        });
        if (doseNotFinish) {
          message.warn(messages('basic-10.key178',{arg1: name})/*请先编辑【{arg1}】*/);
        } else {
          this.setState({ editVisible: true, currentEdit: widget }, () => {
            this.props.handleInnerVisible && this.props.handleInnerVisible(true);
            clearPending();
          });
        }
      } else {
        message.warn(messages('basic-10.key179')/*请先从左侧添加报表元素*/);
      }
    } else {
      this.setState({ editVisible: true, currentEdit: widget }, () => {
        this.props.handleInnerVisible && this.props.handleInnerVisible(true);
        clearPending();
      });
    }
  };

  //处理 拖动 已放置的 图表  （这块有点问题，后面处理 已放置图表的拖动）
  handleOnDragDroppedItem = (widget) => {
    const { widgetList } = this.state;
    let copyData = deepCopy(widgetList);
    copyData = removeArrayItemByKey(copyData, widget, 'id');
    this.setState({ widgetList: copyData });
  };

  // 渲染 所有图表
  renderAllCharts = () => {
    let { widgetList, loading } = this.state;

    return <div className="page-content" ref={ref => this.pageContentRef = ref}>
      <div className="page-graph-groups">
        <GraphicDropTarget
          onStretchItem={(widget) => {
            this.onStretchItem(widget);
          }}
          onDeleteItem={(widget) => {
            this.onDeleteItem(widget);
          }}
          onEditItem={(widget) => {
            this.onEditItem(widget);
          }}
          widgetList={widgetList}
          onDrop={this.handleDrop}
          onDragDroppedItem={this.handleOnDragDroppedItem}
        />
      </div>
    </div>;
  };

  render() {
    const { loading, editVisible, currentEdit, sourceReportIdArray, criteriaData, customReportName, searchForm } = this.state;
    return (
      <div className="custom-report-wrapper">
        <Spin spinning={loading}>
          <div style={{ height: '100vh' }}>
            {this.renderPageHeader()}
            <div className={'page-body'}>
              <div className="left">
                {this.renderPageContentLeft()}
              </div>
              <div className="right" ref={ref => this.rightRef = ref}>
                {searchForm.length ?
                  <div className='advanced-search-box'>
                    <AdvancedSearch
                      pinnedList={searchForm.map(item => item.id)}
                      searchButton={{
                        props: { disabled: true },
                        text: messages('common.search')/*搜索*/
                      }}
                      resetButton={{
                        props: { disabled: true },
                        text: messages('common.reset')/*重置*/
                      }}
                      title={customReportName}
                      searchForm={searchForm}
                      notLoadWhenMount
                      hide={['advanced-pinned-list']}
                    />
                  </div> : null
                }
                <div className="page-controller" onClick={() => {
                  this.onEditItem(criteriaData[0] || criteriaTemplateList[0], true);
                }}>
                  <span><Icon type="filter"/>{messages('basic-10.key101')/*编辑筛选器*/}</span>
                </div>
                {this.renderAllCharts()}
              </div>
            </div>
          </div>
        </Spin>
        {editVisible && !loading &&
        <FullScreen animateIn="fadeIn" animateOut="fadeOut" style={{ background: '#f7f8fa' }}>
          <EditCustomReport
            sourceReportIdArray={sourceReportIdArray}
            customReportData={this.props.customReportData}
            confirmOpened={this.props.confirmOpened}
            currentEdit={currentEdit}
            onCancel={(dontRefresh) => {
              this.setState({ editVisible: false }, () => {
                this.props.handleInnerVisible && this.props.handleInnerVisible(false);
              });
              !dontRefresh && this.initData();
            }}
          />
        </FullScreen>
        }
      </div>
    );
  }
}

CustomReport.propTypes = {
  onCancel: React.PropTypes.func
};

export default withDragDropContext(CustomReport);
